use anyhow::Result;
use std::path::{Path, PathBuf};
use std::fs;
use tokio::fs as async_fs;
use shared::types::{User, PermissionType};

pub mod virtual_fs;
pub mod operations;

use operations::FileOperations;
use virtual_fs::VirtualFileSystem;

pub struct FileSystemManager {
    base_path: PathBuf,
    file_operations: FileOperations,
    virtual_fs: VirtualFileSystem,
}

impl FileSystemManager {
    pub fn new(base_path: PathBuf) -> Self {
        Self { 
            base_path,
            file_operations: FileOperations::new(),
            virtual_fs: VirtualFileSystem::new(),
        }
    }
    
    /// 获取用户的根目录路径
    pub fn get_user_home_path(&self, user: &User) -> PathBuf {
        self.base_path.join(&user.home_directory)
    }
    
    /// 规范化路径，防止目录遍历攻击
    pub fn normalize_path(&self, user: &User, path: &str) -> Result<PathBuf> {
        let user_home = self.get_user_home_path(user);
        
        // 移除开头的斜杠
        let clean_path = path.trim_start_matches('/');
        
        // 构建完整路径
        let full_path = if clean_path.is_empty() {
            user_home.clone()
        } else {
            user_home.join(clean_path)
        };
        
        // 规范化路径
        let normalized = full_path.canonicalize().unwrap_or(full_path);
        
        // 确保路径在用户目录内
        if !normalized.starts_with(&user_home) {
            return Err(anyhow::anyhow!("Path traversal attack detected"));
        }
        
        Ok(normalized)
    }
    
    /// 检查文件是否存在
    pub async fn file_exists(&self, user: &User, path: &str) -> Result<bool> {
        let normalized_path = self.normalize_path(user, path)?;
        Ok(normalized_path.exists())
    }
    
    /// 检查是否为目录
    pub async fn is_directory(&self, user: &User, path: &str) -> Result<bool> {
        let normalized_path = self.normalize_path(user, path)?;
        Ok(normalized_path.is_dir())
    }
    
    /// 获取文件大小
    pub async fn get_file_size(&self, user: &User, path: &str) -> Result<u64> {
        let normalized_path = self.normalize_path(user, path)?;
        let metadata = async_fs::metadata(&normalized_path).await?;
        Ok(metadata.len())
    }
    
    /// 创建目录
    pub async fn create_directory(&self, user: &User, path: &str) -> Result<()> {
        let normalized_path = self.normalize_path(user, path)?;
        async_fs::create_dir_all(&normalized_path).await?;
        Ok(())
    }
    
    /// 删除文件或目录
    pub async fn delete_path(&self, user: &User, path: &str) -> Result<()> {
        let normalized_path = self.normalize_path(user, path)?;
        
        if normalized_path.is_dir() {
            async_fs::remove_dir_all(&normalized_path).await?;
        } else {
            async_fs::remove_file(&normalized_path).await?;
        }
        
        Ok(())
    }
    
    /// 重命名文件或目录
    pub async fn rename_path(&self, user: &User, from: &str, to: &str) -> Result<()> {
        let from_path = self.normalize_path(user, from)?;
        let to_path = self.normalize_path(user, to)?;
        
        async_fs::rename(&from_path, &to_path).await?;
        Ok(())
    }

    /// 获取文件操作器
    pub fn file_operations(&self) -> &FileOperations {
        &self.file_operations
    }

    /// 获取虚拟文件系统
    pub fn virtual_fs(&self) -> &VirtualFileSystem {
        &self.virtual_fs
    }

    /// 获取文件修改时间
    pub async fn get_file_modified_time(&self, user: &User, path: &str) -> Result<std::time::SystemTime> {
        let normalized_path = self.normalize_path(user, path)?;
        let metadata = async_fs::metadata(&normalized_path).await?;
        Ok(metadata.modified()?)
    }

    /// 获取目录列表
    pub async fn list_directory(&self, user: &User, path: &str) -> Result<Vec<operations::DirEntry>> {
        let normalized_path = self.normalize_path(user, path)?;
        self.file_operations.list_directory(&normalized_path).await
    }
}
